#include "watchpoint.h"
#include "expr.h"


static WP *head, *free_;

void init_wp_pool() {
	int i;
	for(i = 0; i < NR_WP; i ++) {
		wp_pool[i].NO = i;
		wp_pool[i].next = &wp_pool[i + 1];
		wp_pool[i].is_used = 0;
		wp_pool[i].pre_val = 0;
		wp_pool[i].val = 0;
	}
	wp_pool[NR_WP - 1].next = NULL;

	head = NULL;
	free_ = wp_pool;
}

/* TODO: Implement the functionality of watchpoint */

// add a watch by input a expression as arg
int wpAdd(char* arg){
	int i;
	for(i = 0; i < NR_WP; ++ i){
		if(wp_pool[i].is_used == false){
			strcpy(wp_pool[i].expr, arg);
			wp_pool[i].val = expr(wp_pool[i].expr, &wp_pool[i].is_used);
			wp_pool[i].pre_val = wp_pool[i].val;
			break;
		}
	}
	return 0;
}

// delete a watchpoint by given a number id
int wpDel(char* arg){
	bool success;
	wp_pool[expr(arg, &success)].is_used = false;
	return 0;
}

// update all watchpoints
int wpUpdate(){
	int i;
	for(i = 0; i < NR_WP; ++ i){
		if(wp_pool[i].is_used == true){
			wp_pool[i].val = expr(wp_pool[i].expr, &wp_pool[i].is_used);
			if(wp_pool[i].is_used == false){
				GUI_printf("\33[1;31mThe watchpoint %d has encounter a error,previous value is %d\33[0m\n", wp_pool[i].NO, wp_pool[i].pre_val);
				GUI_printf("do you want to ingore this error? [y/n]\n");
				char c;
				scanf("%c", &c);
				if(c == 'y') {
					wp_pool[i].is_used = true;
					wp_pool[i].val = wp_pool[i].pre_val;
				}
			}
		}
	}
	return 0;
}

// check all watchpoints and report which val has changed
int wpCheck(){
	int flag = false;
	int i;
	for(i = 0; i < NR_WP; ++ i){
		if((wp_pool[i].is_used == true) && (wp_pool[i].pre_val != wp_pool[i].val)){
			flag = true;
			GUI_printf("watchpoint %d:\n", wp_pool[i].NO);
			GUI_printf("expr: %s\n", wp_pool[i].expr);
			GUI_printf("pre_val: %d (0x%x)\n", wp_pool[i].pre_val, wp_pool[i].pre_val);
			GUI_printf("now_val: %d (0x%x)\n", wp_pool[i].val, wp_pool[i].val);
			wp_pool[i].pre_val = wp_pool[i].val;
		}
	}
	return flag;
}

